package com.hzit.canal.listener;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.xpand.starter.canal.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@CanalEventListener
public class RedisDatabaseSyncListener {

	@Autowired
	private StringRedisTemplate redisTemplate;

	/**
	 * 1. 对插入事件的监听
	 */
	// @InsertListenPoint(table = "tb_brand")
	public void onEvent(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
		//1.1 获取插入后的数据的列表
		List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
		System.out.println("插入后的数据：");
		System.out.println("--------------------------------------------");
		for (CanalEntry.Column column : afterColumnsList) {
			//1.1.1 获取要插入列名
			String name = column.getName();
			//1.1.2 获取要插入的这列的值
			String value = column.getValue();
			//1.1.3 打印
			System.out.println(name + "---->" + value);
		}
	}

	/**
	 * 2. 修改事件的监听
	 */
	// @UpdateListenPoint
	public void onEvent1(CanalEntry.RowData rowData) {
		System.out.println("修改后的数据如下：");
		System.out.println("--------------------------------------------");
		for (CanalEntry.Column column : rowData.getAfterColumnsList()) {
			String name = column.getName();
			String value = column.getValue();
			System.out.println(name + "---->" + value);
		}
	}

	/**
	 * 3. 删除事件的监听
	 */
	// @DeleteListenPoint
	public void onEvent3(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
		//3.1 获取删除前的数据
		List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
		System.out.println("删除前的数据：");
		System.out.println("--------------------------------------------");
		for (CanalEntry.Column column : beforeColumnsList) {
			String name = column.getName();
			String value = column.getValue();
			System.out.println(name + "---->" + value);
		}
	}

	/**
	 * 4. 自定义事件的监听
	 */
	@ListenPoint(table = {"tb_brand"},
			eventType = {
					CanalEntry.EventType.UPDATE,
					CanalEntry.EventType.INSERT,
					CanalEntry.EventType.DELETE}
	)
	public void onEvent4(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
		System.out.println("自定义事件监听");
		System.out.println("eventType = " + eventType.getNumber());
		if (eventType == CanalEntry.EventType.INSERT) {   // 插入操作
			List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
			System.out.println("插入后的数据：");
			System.out.println("--------------------------------------------");
			for (CanalEntry.Column column : afterColumnsList) {
				//1.1.1 获取要插入列名
				String name = column.getName();
				//1.1.2 获取要插入的这列的值
				String value = column.getValue();
				//1.1.3 打印
				System.out.println(name + "---->" + value);
			}
		}
		if(eventType  == CanalEntry.EventType.UPDATE){     // 修改操作
			// System.out.println("修改后的数据如下：");
			// System.out.println("--------------------------------------------");
			// for (CanalEntry.Column column : rowData.getAfterColumnsList()) {
			// 	String name = column.getName();
			// 	String value = column.getValue();
			// 	System.out.println(name + "---->" + value);
			// }

			// 将修改后的数据同步到redis中
			//1. 得到数据库中修改完的数据
			Map<String,String> map = new HashMap<>();
			for (CanalEntry.Column column : rowData.getAfterColumnsList()) {
				String name = column.getName();     // 列名
				name = StrUtil.toCamelCase(name);
				String value = column.getValue();   // 列的值
				map.put(name,value);
			}
			//2. 清除redis中的值
			//2.1 根据redis的key清空redis
			String key = map.get("id") + "";
			redisTemplate.delete(key);
			//2.2 重新放数据到redis中
			redisTemplate.opsForValue().set(key, JSON.toJSONString(map));
		}
		if(eventType == CanalEntry.EventType.DELETE){     // 删除操作
			List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
			System.out.println("删除前的数据：");
			System.out.println("--------------------------------------------");
			for (CanalEntry.Column column : beforeColumnsList) {
				String name = column.getName();
				String value = column.getValue();
				System.out.println(name + "---->" + value);
			}
		}

	}

}
